//
// Copyright (c) 2009 All Right Reserved
//
// vl
//
// 2009-01-01
// Contains ...
namespace LargoCommon.Music
{
using JetBrains.Annotations;
using LargoCommon.Abstract;
using LargoCommon.Interfaces;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
/// A musical content.
public class MusicalContent : IMusicalContent
{
#region Constructors
/// Initializes a new instance of the class.
public MusicalContent() {
this.Header = MusicalHeader.GetDefaultMusicalHeader;
}
#endregion
#region Properties
/// Gets or sets the name.
/// The name.
public string Name { get; set; }
/// Gets or sets the header.
/// The header.
public MusicalHeader Header { get; set; }
/// Gets or sets the lines.
/// The lines.
public virtual List ContentLines { get; set; }
/// Gets or sets bars.
/// The bars.
public virtual List ContentBars { get; set; }
///
/// Gets the content elements.
///
///
/// The content elements.
///
public IList ContentElements {
get {
var elems = new List();
foreach (var bar in this.ContentBars) {
elems.AddRange(bar.Elements);
}
return elems;
}
}
#endregion
#region Naming
///
/// Gets the name and file.
///
/// Property description.
public string FullName => string.Format(CultureInfo.InvariantCulture, "{0}_{1}", this.Header.FileName, this.Header.Name.ClearSpecialChars().Trim());
///
/// Gets the name of the number and.
///
///
/// The name of the number and.
///
public string NumberAndName => string.Format(CultureInfo.InvariantCulture, "{0,4}/{1}", this.Header.Number, this.Header.Name);
#endregion
#region Properties
///
/// Gets or sets a value indicating whether [contains music].
///
///
/// true if [contains music]; otherwise, false.
///
public bool ContainsMusic { get; set; }
/// Gets total duration of the block.
/// Property description.
/// Returns value.
[UsedImplicitly]
public long TotalDuration {
get {
long num = this.Header.System.RhythmicOrder * this.Header.NumberOfBars;
return num;
}
}
///
/// Gets or sets the tonality key.
///
///
/// The tonality key.
///
public TonalityKey TonalityKey { get; set; }
///
/// Gets or sets the tonality genus.
///
///
/// The tonality genus.
///
public TonalityGenus TonalityGenus { get; set; }
///
/// Gets the metric value.
///
/// Property description.
[UsedImplicitly]
public string MetricValue => this.Header.Metric.MetricValue;
///
/// Gets the order value.
///
/// Property description.
[UsedImplicitly]
public string OrderValue => this.Header.System.OrderValue;
#endregion
#region Add content
/// Adds a bar.
/// The given bar.
public void AddBar(IAbstractBar givenBar) {
this.ContentBars.Add(givenBar);
var elements = (List)givenBar.Elements;
if (elements == null) {
return;
}
var lastBar = this.ContentBars.LastOrDefault();
if (lastBar == null) {
return;
}
foreach (var line in this.ContentLines) {
var lastElement = lastBar.GetElement(line.LineIdent);
MusicalElement element;
if (lastElement != null) {
var status = (LineStatus)lastElement.Status.Clone();
element = new MusicalElement(status, lastElement);
}
else {
element = new MusicalElement();
}
element.Bar = givenBar;
element.Line = line;
elements.Add(element);
}
}
///
/// Adds the content line.
///
/// The line status.
/// Returns value.
public virtual IAbstractLine AddContentLine(LineStatus lineStatus) {
return null;
}
///
/// Adds the elements for line.
///
/// The given new track.
public void AddElementsForLine(IAbstractLine givenLine) {
foreach (var bar in this.ContentBars) {
var element = new MusicalElement {
Bar = bar,
Line = givenLine,
IsLive = true,
IsComposed = true,
Status = (LineStatus)givenLine.FirstStatus.Clone()
};
if (element.Status.LineType == MusicalLineType.None || element.Status.LineType == MusicalLineType.Empty) {
element.Status.LineType = MusicalLineType.Melodic;
}
element.Status.BarNumber = bar.BarNumber; //// 2017/03
//// 2019/01 element.Status.LocalPurpose = givenLine.Purpose; //// 2018/12
//// var elements = ((List)bar.Elements);
//// if (elements == null) { return; }
bar.Elements.Add(element);
}
}
#endregion
///
/// Prepares the block.
///
/// The given harmonic stream.
///
/// Returns value.
///
[UsedImplicitly]
public bool SetHarmonicStream(HarmonicStream givenHarmonicStream) {
//// header.NumberOfBars = givenHarmonicStream.HarmonicBars.Count;
var firstHarBar = givenHarmonicStream?.HarmonicBars.FirstOrDefault();
if (firstHarBar == null) {
return false;
}
this.Header.System.RhythmicOrder = firstHarBar.RhythmicStructure.Order;
foreach (var bar in this.ContentBars) {
if (bar.BarNumber <= 1 || bar.BarNumber >= givenHarmonicStream.HarmonicBars.Count) {
continue;
}
var harmonicBar = givenHarmonicStream.HarmonicBars[bar.BarNumber - 1];
var newHarmonicBar = (HarmonicBar)harmonicBar.Clone();
newHarmonicBar.BarNumber = bar.BarNumber;
bar.SetHarmonicBar(newHarmonicBar);
bool respectHarmonicRhythm = false;
if (respectHarmonicRhythm) {
foreach (var elem in bar.Elements) {
elem.Status = (LineStatus)elem.MusicalLine.FirstStatus.Clone();
elem.Status.RhythmicStructure = harmonicBar.RhythmicStructure;
}
}
}
return true;
}
///
/// Lines the index of track.
///
/// The track identifier.
///
/// Returns value.
///
[UsedImplicitly]
public int LineIndexOfLine(Guid lineIdent) {
var line = (from t in this.ContentLines where t.LineIdent == lineIdent select t).FirstOrDefault();
var idx = this.ContentLines.IndexOf(line);
return idx;
}
}
}